package com.cmf.myproject.service.security.realm;

import java.util.Objects;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import com.cmf.myproject.dal.mybatis.model.User;
import com.cmf.myproject.service.security.authc.MallUsernamePasswordToken;
import com.cmf.myproject.service.security.dto.LoginUserInfo;
import com.cmf.myproject.service.system.sysrole.SysRoleService;
import com.cmf.myproject.service.user.UserService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class UserRealm extends AuthorizingRealm{
	
	@Autowired
	private UserService userService;

	private String supportedLoginType;
	@Autowired
    private SysRoleService sysRoleService;
	
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		Subject subject = SecurityUtils.getSubject();
		LoginUserInfo user = (LoginUserInfo) subject.getPrincipal();
		sysRoleService.roleResourceList(user.getRoleId()).forEach((key,item)->{
    		authorizationInfo.addRole(key);
    		authorizationInfo.addStringPermissions(item);
    	});
		return authorizationInfo;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
	    MallUsernamePasswordToken token = (MallUsernamePasswordToken)authenticationToken;
	    
	    User user = userService.userFindByName(token.getUsername());
	    if (Objects.isNull(user)) {
            throw new UnknownAccountException();
        }
	    
	    LoginUserInfo userInfo = new LoginUserInfo();
	    userInfo.setId(user.getId().toString());
        userInfo.setType(token.getLoginType());
        userInfo.setUserName(user.getUserName());
        userInfo.setNickName(user.getNick());
        userInfo.setRoleId(user.getUserRoleId());
        AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
        		userInfo,
        		user.getPassword(),
                getName());
		return authenticationInfo;
	}

	@Override
	public boolean supports(AuthenticationToken token) {
		if (token instanceof MallUsernamePasswordToken) {
            MallUsernamePasswordToken usernamePasswordToken = (MallUsernamePasswordToken) token;
            return getSupportedLoginType().equals(usernamePasswordToken.getLoginType());
        }
        return false;
	}

	public String getSupportedLoginType() {
		return supportedLoginType;
	}

	public void setSupportedLoginType(String supportedLoginType) {
		this.supportedLoginType = supportedLoginType;
	}
}
